package com.example.demo;


import com.example.demo.domain.Mp4VideoInfo;
import com.example.demo.service.GlobalPropertyMonitor;
import com.example.demo.service.RecordInfo;
import com.example.demo.untils.RtspCheckerUtils;
import com.example.demo.untils.FileCheckerNIO;
import com.example.demo.untils.RTSPConverter;
import com.example.demo.untils.RecordingMp4Utils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.*;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;

import java.io.File;
import java.io.IOException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;

@RestController
@RequestMapping("/stream")
public class StreamController
{

    @Autowired
    private GlobalPropertyMonitor monitor; // 注入单例 Bean

    @Autowired
    private RecordInfo recordInfo; // 注入被监控的对象

    //开始录制
    @GetMapping("/startRecord")
    @CrossOrigin(origins = "*")
    public HashMap  startRecord(String rtspUrl,String fileName)
    {
        rtspUrl="rtsp://127.0.0.1:554/easy1.mp4";
        HashMap map=new HashMap();
        System.out.println("开始录制");
        recordInfo.setMacAddress(getMACAddress());
        recordInfo.setId(fileName);
        recordInfo.setStatus(true);
        recordInfo.setStartTime(new Date());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String formatted = LocalDateTime.now().format(formatter);
        //回退5s，防止漏贞
        recordInfo.setFileName(Long.parseLong(formatted)-5);
        monitor.setTarget(recordInfo); // 设置监控目标
        monitor.startMonitoring();
        ////////////////////
        boolean isAlive =   RtspCheckerUtils.checkRtspStream(rtspUrl);
        if(!isAlive){
            map.put("code",300);
            map.put("msg","未检测到视频流");
            return map;
        }
        RTSPConverter.stopStreaming();
        // fileName= "第一个录播";
        RTSPConverter.startHLSStreaming(rtspUrl,fileName);
        map.put("code",200);
        return  map;
    }

    //开始转换
    @GetMapping("/stopRecord")
    @CrossOrigin(origins = "*")
    public HashMap  stopRecord(String fileName)
    {
        System.out.println("停止录制");
        HashMap map=new HashMap();
        recordInfo.setId(fileName);
        recordInfo.setStatus(false);
        map.put("macAddress",recordInfo.getMacAddress());
        map.put("businessId", recordInfo.getId());
        map.put("businessType","1");
        map.put("recordingStatus","2");//录制完成
        RtspCheckerUtils.sendPostRequest(map);
       // monitor.stopMonitoring(); // 停止监控
        map.put("code",200);
        return  map;
    }


    // 获取rtsp 连接状态
    @GetMapping("/getRstpUrlStatus")
    @CrossOrigin(origins = "*")
    public boolean  getRstpUrlStatus( String rtspUrl)
    {
        boolean isAlive =   RtspCheckerUtils.checkRtspStream(rtspUrl);
        return  isAlive;
    }

    /////更改rtsp 地址
    @GetMapping("/updateRstpUrl")
    @CrossOrigin(origins = "*")
    public HashMap  updateRstpUrl( String rtspUrl)
    {
        HashMap map=new HashMap();
        recordInfo.setRtspUrl(rtspUrl);
        map.put("code",200);
        return map;
    }

    //开始转换
    @GetMapping("/startRstpConvert")
    @CrossOrigin(origins = "*")
    public HashMap  start( String rtspUrl,String fileName)
    {
        boolean isAlive =   RtspCheckerUtils.checkRtspStream(rtspUrl);
        HashMap map=new HashMap();
        if(!isAlive){
            map.put("code",300);
            map.put("msg","未检测到视频流");
            return map;
        }
        // 先停止其他
        System.out.println("开始转换");
        RTSPConverter.stopStreaming();
        rtspUrl="rtsp://127.0.0.1:554/easy1.mp4";
       // fileName= "第一个录播";
        RTSPConverter.startHLSStreaming(rtspUrl,fileName);
        map.put("code",200);
        return  map;
    }


    @GetMapping("/play/{id}/{filename}")
    @CrossOrigin(origins = "*")
    public Resource getStreamFile(@PathVariable String id,@PathVariable String filename) {
        System.out.println("文件id："+id);
        String test1="D:\\jdk18\\hls2\\"+ id +"\\"+filename;
        int maxRetries = 10;
        int retryDelayMs = 1000; // 1秒 = 1000毫秒
        boolean fileExists = FileCheckerNIO.checkFileExists(test1, maxRetries, retryDelayMs);
        System.out.println("----------检测完毕---------------");
        return new FileSystemResource(test1);
    }

//    @GetMapping("/playlast/{filename}")
//    @CrossOrigin(origins = "*")
//    public Resource playlast(@PathVariable String filename) {
//        String test1=RTSPConverter.getOutputDir()+"第一个录播\\"+filename;
//        return new FileSystemResource(test1);
//    }


    @GetMapping("/stop")
    @CrossOrigin(origins = "*")
    public HashMap  stopStream() {
        System.out.println("停止转换");
        int code= RTSPConverter.stopStreaming();
        HashMap map=new HashMap();
        map.put("code",200);
        return map;
    }



    @GetMapping("/myMACAddress")
    @CrossOrigin(origins = "*")
    public String  myMACAddress() {
        String macAddress=getMACAddress();
        return macAddress;
    }


    /**
     * 上传视频
     * @param businessId
     * @return
     * @throws IOException
     * @throws InterruptedException
     * @throws EncoderException
     */
    @GetMapping("/uploadMp4")
    @CrossOrigin(origins = "*")
    public HashMap  uploadMp4(int businessId)  {
        HashMap map=new HashMap();
        String macAddress=getMACAddress();
        Mp4VideoInfo mp4VideoInfo= new Mp4VideoInfo();
        String  mp4filePath ="D:\\jdk18\\hls2Record\\"+businessId+"\\merged.mp4";
        mp4VideoInfo.setLocalPath(mp4filePath);
        mp4VideoInfo.setBusinessId(businessId);
        mp4VideoInfo.setMacAddress(macAddress);
        //视频时长获取
        try {
            File file = new File(mp4filePath);
            if(!file.exists()) {
                RecordingMp4Utils.mergeTSFiles("D:\\jdk18\\hls2Record\\"+businessId,mp4filePath);
            }
            MultimediaObject instance = new MultimediaObject(new File(mp4filePath));
            Long  miss= instance.getInfo().getDuration(); // 返回视频毫秒数
            mp4VideoInfo.setVideoLength(miss);
            String resultMsg=  this.upload(mp4VideoInfo);
            map.put("msg",resultMsg);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code",300);
            map.put("msg",e.getMessage());
        }
        map.put("code",200);
        return  map;
    }

     ////向接口传视频
    public String upload(Mp4VideoInfo mp4VideoInfo){
        String apiUrl = "http://cs.xmmillions.com:18082/client/uploadVideo";
        File videoFile = new File(mp4VideoInfo.getLocalPath());

        // 验证文件是否存在
        if (!videoFile.exists() || !videoFile.isFile()) {
            System.err.println("视频文件不存在或不是有效文件: " + mp4VideoInfo.getLocalPath());
            return "视频文件不存在或不是有效文件: " + mp4VideoInfo.getLocalPath();
        }
        // 创建带超时设置的 HttpClient
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(30_000)    // 30秒连接超时
                .setSocketTimeout(120_000)     // 2分钟传输超时
                .setConnectionRequestTimeout(10_000) // 10秒获取连接超时
                .build();
        try (CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build()) {

            HttpPost httpPost = new HttpPost(apiUrl);
            // 添加通用请求头
            httpPost.setHeader("User-Agent", "VideoUploader/1.0");
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Accept-Charset", "UTF-8");
            // 构建多部分表单实体
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(StandardCharsets.UTF_8); // 设置字符编码
            // 1. 添加视频文件
            builder.addBinaryBody(
                    "videoFile",          // 服务端接收文件的参数名
                    videoFile,       // 文件对象
                    ContentType.create("video/mp4"), // 文件类型
                    videoFile.getName() // 原始文件名
            );
            // 2. 添加其他文本参数
            builder.addTextBody("macAddress", mp4VideoInfo.getMacAddress(), ContentType.TEXT_PLAIN);
            builder.addTextBody("businessId", String.valueOf(mp4VideoInfo.getBusinessId()), ContentType.TEXT_PLAIN);
            builder.addTextBody("businessType", String.valueOf(1), ContentType.TEXT_PLAIN);
            builder.addTextBody("fileType", String.valueOf(1), ContentType.TEXT_PLAIN);
            builder.addTextBody("videoLength", String.valueOf(mp4VideoInfo.getVideoLength()), ContentType.TEXT_PLAIN);
            // 3. 构建请求实体
            HttpEntity multipartEntity = builder.build();
            httpPost.setEntity(multipartEntity);
         //   System.out.println("开始上传视频: " + videoFile.getName() + " (" + formatFileSize(videoFile.length()) + ")");
            // 4. 执行请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                System.out.println("响应状态: " + statusCode);
                System.out.println("响应内容: " + responseBody);
                HashMap map=new HashMap();
                map.put("macAddress",getMACAddress());
                map.put("businessId",mp4VideoInfo.getBusinessId());
                map.put("businessType","1");
                map.put("recordingStatus","4");//商品上传完成
                RtspCheckerUtils.sendPostRequest(map);
                return  "成功";
                // 处理响应
              //  handleUploadResponse(statusCode, responseBody);
            }
        } catch (IOException e) {
           // handleUploadError(e, videoFile);
            return e.getMessage();
        }
    }


    public static String getMACAddress() {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaces.nextElement();
                // 排除虚拟和环回接口
                if (networkInterface.isLoopback() || !networkInterface.isUp()) {
                    continue;
                }
                byte[] mac = networkInterface.getHardwareAddress();
                if (mac != null) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < mac.length; i++) {
                        sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
                    }
                    return sb.toString();
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null; // 如果没有找到有效的MAC地址，返回null
    }

}
